<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
// --------------------------------------------------------- 算法部分 
    var points = [];
    var k = 0; //斜率
    var b = 0; //截距
    var status = 'addPoint';//状态控制


    /**
    * 最小二乘法 y=ax+b
    * 求 k , b 
    * k=(NΣxy-ΣxΣy)/(NΣx^2-(Σx)^2) 
    * b=y(平均)-k*x（平均） 
    * @param points 点集合
    * @return k,b
    */
    function leastSquare(points){
        var sX = 0;//Σx
        var sY = 0;//Σy
        var sXY = 0;//Σxy
        var sXX = 0;//Σx^2
        var n = points.length;
        for (var i = 0; i < points.length; i++) {
            var p = points[i];
            sX += p.x;
            sY += p.y;
            sXX += Math.pow(p.x, 2);
            sXY += p.x * p.y;
        }
        k = (n * sXY - sX * sY) / (n * sXX - Math.pow(sX, 2));
        b = sY/n - k * sX/n;
    }
    /**
    * 根据当前点生成直线
    * y=ax+b
    */
    function execCalc(){
        if(points.length <2){
            alert("请点击创建点，至少要有2个以上");
            return false;
        }
        status = 'calc';//修改状态，不可以再次创建点
        leastSquare(points);
        var minx =points[0].x, maxX=points[0].x;
        for (var i = 1; i < points.length; i++) {
           if(minx > points[i].x){
            minx = points[i].x;
           }
           if(maxX < points[i].x){
            maxX = points[i].x;
           }
        }

        var y1 = minx * k + b;
        var y2 = maxX * k + b;
        addLine(minx,y1,maxX,y2);
    }

// --------------------------------------------------------- 辅助部分 
    /**
    * 显示点坐标
    */
    function showPoints(btn) {
        var cans = document.getElementById("res");
        if(btn.value === '显示点坐标'){
            for (var i = 0; i < points.length; i++) {
                var p = points[i];
                var pSpan = document.createElement('span');
                pSpan.style.position = "absolute";  
                pSpan.style.left =  p.x + 'px';  
                pSpan.style.top =  p.y + 'px';  
                pSpan.appendChild(document.createTextNode("x:"+p.x + ",y:"+p.y));
                cans.appendChild(pSpan);
            }
            cans.style.display='';
            btn.value = '隐藏点坐标'
        }else{
            cans.style.display='none';
            btn.value = '显示点坐标';
        }

        // var d = document.getElementById("cans").getContext("2d");  //2d
        // d.font ='14px Arial';
        // for (var i = 0; i < points.length; i++) {
        //     var p = points[i];
        //     d.fillText("x:"+p.x + ",y:"+p.y,p.x,p.y);
        // }
    }

    /**
    * 添加点
    */
    function addPointHandler(event) {
        if(status === 'addPoint'){
            var x = event.layerX;
            var y = event.layerY;
            addPoint(x,y);
            points.push({x:x, y:y});//添加点到集合
        }
    }

    /**
    * 创建线
    */
    function addLine(startX,startY,endX,endY) {
        var d = document.getElementById("cans").getContext("2d");  //2d
        d.lineWidth=2;     // 线条粗细
        d.moveTo(startX,startY);//起始位置
        d.lineTo(endX,endY); //终止位置
        d.stroke(); // 结束图形
    }

    /**
    * 创建点
    */
    function addPoint(x,y) {
        var d = document.getElementById("cans").getContext("2d");  //2d
        d.fillStyle="red";
        d.fillRect(x,y,10,10);
    }

    </script> 
 </head> 

 <body>
    <input type="button" value="点击计算" onclick="execCalc()">
    <input type="button" value="显示点坐标" onclick="showPoints(this)"><br/>
    <div id="res" style="position: absolute;left: 100px;top: 50px; width:500px; height: 500px; display: none; z-index: 999;" ></div> 
    <canvas id="cans" width="500px" height="500px" style="background-color: rgb(201, 255, 202);position: absolute;left: 100px;top: 50px;" onmousedown="addPointHandler(event)">浏览器不支持canvas</canvas> 
 </body> 
</html>